#pragma once
#include "DataPoint.h"
#include "ImportData.h"
#include <iostream>
#include <queue>
#include <Eigen/Eigen>
#include "GridElement.h"
#include "Edge.h"
#include "Side.h"
#include <math.h>
#include <map>
#include <string>

using namespace std;
using namespace Eigen;

class Marching
{
public:
	//EIGEN_MAKE_ALIGNED_OPERATOR_NEW; //Needed to have fixed Eigen structures as members of class
	Marching();
	Marching(ImportData* d);
	//2D
	queue<GridElement<Edge>> march2d(int s);
	Edge checkEdge(Edge &e); //Locates the optimal exit point from "list of neighbors", returns "exit point edge"
	queue<GridElement<Edge>> constructRidges(queue<GridElement<Edge>> gridelements);
	queue<GridElement<Edge>> getRidgeLines2d();
	void setConvex(bool c);
	//3D
	queue<GridElement<Side>> temp_lines;
	queue<GridElement<Side>> march3d();
	Edge checkEdge3d(Edge &e);
	//queue<GridElement<Edge>> constructRidges3d(queue<GridElement<Edge>> gridelements);
	queue<GridElement<Side>> constructSurface(queue<GridElement<Side>> gridelements);
	void locateFaceLines(queue<GridElement<Side>> gridelements);
	void constructTriangles();
	//queue<GridElement<Side>> getRidgeLines3d();
	int vertCount,triCount;
	~Marching(void);
	

private:
	std::vector<VectorXi> face,f_adjacent,f_opposite;
	ImportData* data;
	queue<GridElement<Side>> grid_lines3d,s_lines;
	queue<GridElement<Edge>> grid_lines2d;
	int compareLines(VectorXi a,VectorXi b);
	void printVector_eigen(std::vector<VectorXd> v);
	void printVector_int(std::vector<int> v);
	int nDim,nCount; //values to store the dimension of a neighbor, and the number of edges in a gridcell.
	int slice; //what slice is being marched on
	bool mostconvex;
	
};
